package zxj.baidu.map.service;

import java.io.IOException;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;

import zxj.baidu.map.api.SearchApi;
import zxj.baidu.map.domain.BaiduMapCityCode;
import zxj.baidu.map.domain.BaiduMapPoi;
import zxj.baidu.map.domain.param.BaiduMapPoiParam;
import zxj.baidu.map.mapper.BaiduMapCityCodeMapper;
import zxj.baidu.map.mapper.BaiduMapPoiMapper;
import zxj.baidu.map.utils.MapUtils;

/**
 * 百度地图POI Service
 * 
 * @author zhuxuejiang
 *
 */
@Service
public class BaiduMapPoiService {

	private static final Logger LOGGER = LoggerFactory.getLogger(BaiduMapPoiService.class);

	private static final String STATUS = "status";
	private static final int PAGE_SIZE = 20;

	@Autowired
	private SearchApi searchApi;

	@Autowired
	private BaiduMapPoiMapper baiduMapPoiMapper;

	@Autowired
	private BaiduMapCityCodeMapper baiduMapCityCodeMapper;

	/**
	 * 行政区划区域检索
	 * 
	 * @param query 检索关键字
	 * @return 检索结果记录总数
	 */
	public int regionSearch(String query) {
		int total = 0;

		List<BaiduMapCityCode> cityList = baiduMapCityCodeMapper.selectAll();
		for (BaiduMapCityCode city : cityList) {
			LOGGER.debug("regionSearch result \r\n -------------------------------------------------- \r\n"
					+ city.getName());
			total += regionSearchStartFromPage(city.getName(), query, 0);
		}

		return total;
	}

	/**
	 * 行政区划区域检索
	 * 
	 * @param region 检索行政区划区域
	 * @param query  检索关键字
	 * @return 检索结果记录总数
	 */
	public int regionSearch(String region, String query) {
		return regionSearchStartFromPage(region, query, 0);
	}

	/**
	 * 行政区划区域检索
	 * 
	 * @param region  检索行政区划区域
	 * @param query   检索关键字
	 * @param pageNum 分页页码，默认为0,0代表第一页，1代表第二页，以此类推。
	 * @return 检索结果记录总数
	 */
	@SuppressWarnings("unchecked")
	public int regionSearchStartFromPage(String region, String query, int pageNum) {
		pageNum = pageNum < 0 ? 0 : pageNum;
		int total = 0;

		Map<String, Object> resultMap = null;
		try {
			resultMap = searchApi.regionSearch(region, query, PAGE_SIZE, pageNum);
		} catch (Exception e) {
			LOGGER.error("", e);
		}

		// 使用个人用户开发时，请求频繁会被限制访问。增加延迟时间。
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			LOGGER.error("", e);
		}

		if (null == resultMap || (int) resultMap.get(STATUS) != 0) {
			LOGGER.debug("regionSearch result \r\n" + resultMap);
			return 0;
		}

		List<Map<String, Object>> results = (List<Map<String, Object>>) resultMap.get("results");

		if (null == results || results.size() == 0) {
			return 0;
		}

		for (Map<String, Object> result : results) {
			BaiduMapPoi poi = null;
			try {
				poi = MapUtils.map2Object(MapUtils.keyLowerUnderScore2LowerCamel(result), BaiduMapPoi.class);
			} catch (IOException e) {
				LOGGER.error("", e);
			}
			if (null == poi || StringUtils.isBlank(poi.getUid())) {
				continue;
			}

			BaiduMapPoi existedPoi = baiduMapPoiMapper.selectByPrimaryKey(poi.getUid());
			if (null == existedPoi) {
				baiduMapPoiMapper.insertSelective(poi);
			} else {
				baiduMapPoiMapper.updateByPrimaryKeySelective(poi);
			}

			total++;
		}

		if (results.size() < PAGE_SIZE) {
			return total;
		}

		total += regionSearchStartFromPage(region, query, ++pageNum);
		return total;
	}

	/**
	 * 查询省份列表
	 * 
	 * @return 省份列表
	 */
	public List<String> selectProvinceList() {
		return baiduMapPoiMapper.selectProvinceList();
	}

	/**
	 * 查询城市列表
	 * 
	 * @param province 省份
	 * @return 城市列表
	 */
	public List<String> selectCityList(String province) {
		return baiduMapPoiMapper.selectCityList(province);
	}

	/**
	 * 查询区县列表
	 * 
	 * @param city 城市
	 * @return 区县列表
	 */
	public List<String> selectAreaList(String city) {
		return baiduMapPoiMapper.selectAreaList(city);
	}

	/**
	 * 分页查询百度地图POI
	 * 
	 * @param param 查询参数
	 * @return 分页查询结果
	 */
	public Page<BaiduMapPoi> selectByPage(BaiduMapPoiParam param) {
		PageHelper.startPage(param.getPageNum(), param.getPageSize());
		return baiduMapPoiMapper.selectByPage(param);
	}

	/**
	 * 查询百度地图POI列表
	 *
	 * @param param 查询参数
	 * @return 百度地图POI列表
	 */
	public List<BaiduMapPoi> selectList(BaiduMapPoiParam param) {
		return baiduMapPoiMapper.selectList(param);
	}

}
